package com.gen.utils;

import com.xuan.xutils.utils.DateUtils;
import javafx.util.Pair;

import java.sql.Timestamp;
import java.util.*;

/**
 * Created by Administrator on 2016/9/27.
 */
public class RandomUtils {

    //双重校验锁获取一个Random单例
    public static Random getRandom() {
        return new Random();
    }
    
    // 根据长度获取字符串
    public static String getRandomNumber(int len){
        StringBuffer str = new StringBuffer();
        for (int i=0;i<len;i++){
            str.append(new Random().nextInt(10));
        }
        return str.toString();
    }

    /**
     * 获得一个[0,max)之间的随机整数。
     * @param max
     * @return
     */
    public static int getRandomInt(int max) {
        return getRandom().nextInt(max);
    }

    /**
     * 获得一个[min, max]之间的随机整数
     * @param min
     * @param max
     * @return
     */
    public static int getRandomInt(int min, int max) {
        return getRandom().nextInt(max-min+1) + min;
    }

    /**
     * 获得一个[0,max)之间的长整数。
     * @param max
     * @return
     */
    public static long getRandomLong(long max) {
        return getRandom().nextLong();
    }

    /**
     * 从数组中随机获取一个元素
     * @param array
     * @return
     */
    public static <E> E getRandomElement(E[] array){
        return array[getRandomInt(array.length)];
    }

    /**
     * 从list中随机取得一个元素
     * @param list
     * @return
     */
    public static <E> E getRandomElement(List<E> list){
        return list.get(getRandomInt(list.size()));
    }

    /**
     * 从set中随机取得一个元素
     * @param set
     * @return
     */
    public static <E> E getRandomElement(Set<E> set){
        int rn = getRandomInt(set.size());
        int i = 0;
        for (E e : set) {
            if(i==rn){
                return e;
            }
            i++;
        }
        return null;
    }

    /**
     * 从map中随机取得一个key
     * @param map
     * @return
     */
    public static <K, V> K getRandomKeyFromMap(Map<K, V> map) {
        int rn = getRandomInt(map.size());
        int i = 0;
        for (K key : map.keySet()) {
            if(i==rn){
                return key;
            }
            i++;
        }
        return null;
    }

    /**
     * 从map中随机取得一个value
     * @param map
     * @return
     */
    public static <K, V> V getRandomValueFromMap(Map<K, V> map) {
        int rn = getRandomInt(map.size());
        int i = 0;
        for (V value : map.values()) {
            if(i==rn){
                return value;
            }
            i++;
        }
        return null;
    }

    /**
     * 生成一个n位的随机数，用于验证码等
     * @param n
     * @return
     */
    public static String getRandNumber(int n) {
        String rn = "";
        if (n > 0 && n < 10) {
            //Random r = new Random();
            StringBuffer str = new StringBuffer();
            for (int i = 0; i < n; i++) {
                str.append('9');
            }
            int num = Integer.parseInt(str.toString());
            while (rn.length() < n) {
                rn = String.valueOf(getRandom().nextInt(num));
            }
        } else {
            rn = "0";
        }
        return rn;
    }

    // 权重分配算法
    public static class WeightRandomStrategy<K, V extends Number> {

        private TreeMap<Double, K> weightMap = new TreeMap<>();

        public WeightRandomStrategy(List<Pair<K, V>> list) {
            for (Pair<K, V> pair : list) {
                double lastWeight = this.weightMap.size() == 0 ? 0 : this.weightMap.lastKey();
                this.weightMap.put(pair.getValue().doubleValue() + lastWeight, pair.getKey());
            }
        }

        public K random() {
            double randomWeight = this.weightMap.lastKey() * Math.random();
            SortedMap<Double, K> tailMap = this.weightMap.tailMap(randomWeight, false);
            return this.weightMap.get(tailMap.firstKey());
        }
    }

    /**
     * 韩国姓+英文名     5%
     * 韩国姓.韩国名      10%
     * 英文名                10%
     * 韩国名+表情       10%
     * 韩国姓名            10%
     * 英文名+数字       5%
     * 韩国姓_韩国名     10%
     * 韩国名字+年、生日随机    10%
     * 英文名+（空格）韩国姓    5%
     * 韩国姓+（英文名）        5%
     * 韩国姓（空格）韩国名     10%
     * 韩国姓.韩国名+表情        5%
     * 韩国姓名+特色符号         5%
     * @return
     */
    public static String getKoreType(){
        List<Pair<String, Integer>> list = new ArrayList<>();
        list.add(new Pair<>("1", 5));
        list.add(new Pair<>("2", 10));
        list.add(new Pair<>("3", 10));
        list.add(new Pair<>("4", 10));
        list.add(new Pair<>("5", 10));
        list.add(new Pair<>("6", 5));
        list.add(new Pair<>("7", 10));
        list.add(new Pair<>("8", 10));
        list.add(new Pair<>("9", 5));
        list.add(new Pair<>("10", 5));
        list.add(new Pair<>("11", 10));
        list.add(new Pair<>("12", 5));
        list.add(new Pair<>("13", 5));
        WeightRandomStrategy<String, Integer> strategy = new WeightRandomStrategy<>(list);
        return strategy.random();
    }

    /**
     * 名姓     5%
     * 名       10%
     * 名_姓    5%
     * 名.姓    30%
     * 名 姓    50%
     */
    public static String getItaType(){
        List<Pair<String, Integer>> list = new ArrayList<>();
        list.add(new Pair<>("1", 5));
        list.add(new Pair<>("2", 10));
        list.add(new Pair<>("3", 5));
        list.add(new Pair<>("4", 30));
        list.add(new Pair<>("5", 50));
        WeightRandomStrategy<String, Integer> strategy = new WeightRandomStrategy<>(list);
        return strategy.random();
    }

    // 生成制定范围日期
    public static String [] randomHireday() {
        int startYear = 1990;                                  //指定随机日期开始年份
        int endYear = 2005;                                    //指定随机日期结束年份(含)
        long start = Timestamp.valueOf(startYear + 1 + "-1-1 0:0:0").getTime();
        long end = Timestamp.valueOf(endYear + "-1-1 0:0:0").getTime();
        long ms = (long) ((end - start) * Math.random() + start);    //获得了符合条件的13位毫秒数
        Date hireday = new Date(ms);
        String date = DateUtils.date2String(hireday,"yyyyMMdd");
        String year = date.substring(0,4);
        String days = date.substring(4,8);
        String [] array = {year,days};
        return array;
    }

    public static String getKoreNumber(){
        List<Pair<String, Integer>> list = new ArrayList<>();
        list.add(new Pair<>("1", 30));
        list.add(new Pair<>("2", 70));
        WeightRandomStrategy<String, Integer> strategy = new WeightRandomStrategy<>(list);
        String res = strategy.random();
        String [] array =  randomHireday();
        if(res.equals("1")){
            return array[0];
        }else {
            return array[1];
        }
    }

    public static String getRandomWeight(int min,int max){
        List<Pair<String, Integer>> list = new ArrayList<>();
        list.add(new Pair<>("1", min));
        list.add(new Pair<>("2", max));
        WeightRandomStrategy<String, Integer> strategy = new WeightRandomStrategy<>(list);
        String res = strategy.random();
        return res;
    }

    public static int itaRandomWeight(){
        double d = Math.random();
        if(d <= 0.2){
            return 2;
        }else if(d == 0.1){
            return 1;
        }else {
            return 0;
        }
    }

    public static int fantiRandom(){
        double d = Math.random();
        if(d <= 0.7){
            return 1;
        }else if(d == 0.8){
            return 2;
        }else {
            return 3;
        }
    }
}
